symboliccolor: Split out HSLA code
authorBenjamin Otte <otte@redhat.com>
Thu, 8 Nov 2012 14:26:33 +0000 (15:26 +0100)
committerBenjamin Otte <otte@redhat.com>
Thu, 8 Nov 2012 22:34:05 +0000 (23:34 +0100)
gtk/Makefile.am
gtk/gtkhsla.c [new file with mode: 0644]
gtk/gtkhslaprivate.h [new file with mode: 0644]
gtk/gtksymboliccolor.c

index 7e9ebffea3b94af68394cf589de8064ef5de4cc7..ca7dbaaa5c4f65677c81af73ec4ccc7cd38637ad 100644 (file)
@@ -478,6 +478,7 @@ gtk_private_h_sources =             \
        gtkfontchooserprivate.h \
        gtkfontchooserutils.h   \
        gtkgradientprivate.h    \
+       gtkhslaprivate.h        \
        gtkiconcache.h          \
        gtkiconhelperprivate.h  \
        gtkiconviewprivate.h    \
@@ -719,6 +720,7 @@ gtk_base_c_sources =                \
        gtkframe.c              \
        gtkgradient.c           \
        gtkgrid.c               \
+       gtkhsla.c               \
        gtkiconcache.c          \
        gtkiconcachevalidator.c \
        gtkiconfactory.c        \
diff --git a/gtk/gtkhsla.c b/gtk/gtkhsla.c
new file mode 100644 (file)
index 0000000..a788497
--- /dev/null
@@ -0,0 +1,185 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkhslaprivate.h"
+
+#include <math.h>
+
+void
+_gtk_hsla_init (GtkHSLA *hsla,
+                double   hue,
+                double   saturation,
+                double   lightness,
+                double   alpha)
+{
+  g_return_if_fail (hsla != NULL);
+
+  if (hue >= 0)
+    hsla->hue = fmod (hue, 360);
+  else
+    hsla->hue = fmod (hue, 360) + 360;
+  hsla->saturation = CLAMP (saturation, 0, 1);
+  hsla->lightness = CLAMP (lightness, 0, 1);
+  hsla->alpha = CLAMP (alpha, 0, 1);
+}
+
+void
+_gtk_hsla_init_from_rgba (GtkHSLA       *hsla,
+                          const GdkRGBA *rgba)
+{
+  gdouble min;
+  gdouble max;
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble delta;
+  
+  g_return_if_fail (hsla != NULL);
+  g_return_if_fail (rgba != NULL);
+
+  red = rgba->red;
+  green = rgba->green;
+  blue = rgba->blue;
+  
+  if (red > green)
+    {
+      if (red > blue)
+        max = red;
+      else
+        max = blue;
+      
+      if (green < blue)
+        min = green;
+      else
+        min = blue;
+    }
+  else
+    {
+      if (green > blue)
+        max = green;
+      else
+        max = blue;
+      
+      if (red < blue)
+        min = red;
+      else
+        min = blue;
+    }
+  
+  hsla->lightness = (max + min) / 2;
+  hsla->saturation = 0;
+  hsla->hue = 0;
+  hsla->alpha = rgba->alpha;
+  
+  if (max != min)
+    {
+      if (hsla->lightness <= 0.5)
+        hsla->saturation = (max - min) / (max + min);
+      else
+        hsla->saturation = (max - min) / (2 - max - min);
+      
+      delta = max -min;
+      if (red == max)
+        hsla->hue = (green - blue) / delta;
+      else if (green == max)
+        hsla->hue = 2 + (blue - red) / delta;
+      else if (blue == max)
+        hsla->hue = 4 + (red - green) / delta;
+      
+      hsla->hue *= 60;
+      if (hsla->hue < 0.0)
+        hsla->hue += 360;
+    }
+}
+
+void
+_gdk_rgba_init_from_hsla (GdkRGBA       *rgba,
+                          const GtkHSLA *hsla)
+{
+  gdouble hue;
+  gdouble lightness;
+  gdouble saturation;
+  gdouble m1, m2;
+  
+  lightness = hsla->lightness;
+  saturation = hsla->saturation;
+  
+  if (lightness <= 0.5)
+    m2 = lightness * (1 + saturation);
+  else
+    m2 = lightness + saturation - lightness * saturation;
+  m1 = 2 * lightness - m2;
+  
+  rgba->alpha = hsla->alpha;
+
+  if (saturation == 0)
+    {
+      rgba->red = lightness;
+      rgba->green = lightness;
+      rgba->blue = lightness;
+    }
+  else
+    {
+      hue = hsla->hue + 120;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+      
+      if (hue < 60)
+        rgba->red = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        rgba->red = m2;
+      else if (hue < 240)
+        rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        rgba->red = m1;
+      
+      hue = hsla->hue;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+      
+      if (hue < 60)
+        rgba->green = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        rgba->green = m2;
+      else if (hue < 240)
+        rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        rgba->green = m1;
+      
+      hue = hsla->hue - 120;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+      
+      if (hue < 60)
+        rgba->blue = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        rgba->blue = m2;
+      else if (hue < 240)
+        rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        rgba->blue = m1;
+    }
+}
+
diff --git a/gtk/gtkhslaprivate.h b/gtk/gtkhslaprivate.h
new file mode 100644 (file)
index 0000000..3cc97d9
--- /dev/null
@@ -0,0 +1,47 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_HSLA_PRIVATE_H__
+#define __GTK_HSLA_PRIVATE_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GtkHSLA GtkHSLA;
+
+struct _GtkHSLA {
+  double hue;
+  double saturation;
+  double lightness;
+  double alpha;
+};
+
+void            _gtk_hsla_init              (GtkHSLA          *hsla,
+                                             double            hue,
+                                             double            saturation,
+                                             double            lightness,
+                                             double            alpha);
+void            _gtk_hsla_init_from_rgba    (GtkHSLA          *hsla,
+                                             const GdkRGBA    *rgba);
+/* Yes, I can name that function like this! */
+void            _gdk_rgba_init_from_hsla    (GdkRGBA          *rgba,
+                                             const GtkHSLA    *hsla);
+
+G_END_DECLS
+
+#endif /* __GTK_HSLA_PRIVATE_H__ */
index 658a14cb02c563a8b948402e528d4b0b592a9137..8f312cf4258d6be1670e345ae9f3810069267738 100644 (file)
@@ -18,6 +18,7 @@
 #include "config.h"
 #include "gtkcssrgbavalueprivate.h"
 #include "gtkcssstylepropertyprivate.h"
+#include "gtkhslaprivate.h"
 #include "gtkstylepropertyprivate.h"
 #include "gtksymboliccolorprivate.h"
 #include "gtkstyleproperties.h"
@@ -509,179 +510,21 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color)
   _gtk_css_value_unref ((GtkCssValue *) color);
 }
 
-static void
-rgb_to_hls (gdouble *r,
-            gdouble *g,
-            gdouble *b)
-{
-  gdouble min;
-  gdouble max;
-  gdouble red;
-  gdouble green;
-  gdouble blue;
-  gdouble h, l, s;
-  gdouble delta;
-  
-  red = *r;
-  green = *g;
-  blue = *b;
-  
-  if (red > green)
-    {
-      if (red > blue)
-        max = red;
-      else
-        max = blue;
-      
-      if (green < blue)
-        min = green;
-      else
-        min = blue;
-    }
-  else
-    {
-      if (green > blue)
-        max = green;
-      else
-        max = blue;
-      
-      if (red < blue)
-        min = red;
-      else
-        min = blue;
-    }
-  
-  l = (max + min) / 2;
-  s = 0;
-  h = 0;
-  
-  if (max != min)
-    {
-      if (l <= 0.5)
-        s = (max - min) / (max + min);
-      else
-        s = (max - min) / (2 - max - min);
-      
-      delta = max -min;
-      if (red == max)
-        h = (green - blue) / delta;
-      else if (green == max)
-        h = 2 + (blue - red) / delta;
-      else if (blue == max)
-        h = 4 + (red - green) / delta;
-      
-      h *= 60;
-      if (h < 0.0)
-        h += 360;
-    }
-  
-  *r = h;
-  *g = l;
-  *b = s;
-}
-
-static void
-hls_to_rgb (gdouble *h,
-            gdouble *l,
-            gdouble *s)
-{
-  gdouble hue;
-  gdouble lightness;
-  gdouble saturation;
-  gdouble m1, m2;
-  gdouble r, g, b;
-  
-  lightness = *l;
-  saturation = *s;
-  
-  if (lightness <= 0.5)
-    m2 = lightness * (1 + saturation);
-  else
-    m2 = lightness + saturation - lightness * saturation;
-  m1 = 2 * lightness - m2;
-  
-  if (saturation == 0)
-    {
-      *h = lightness;
-      *l = lightness;
-      *s = lightness;
-    }
-  else
-    {
-      hue = *h + 120;
-      while (hue > 360)
-        hue -= 360;
-      while (hue < 0)
-        hue += 360;
-      
-      if (hue < 60)
-        r = m1 + (m2 - m1) * hue / 60;
-      else if (hue < 180)
-        r = m2;
-      else if (hue < 240)
-        r = m1 + (m2 - m1) * (240 - hue) / 60;
-      else
-        r = m1;
-      
-      hue = *h;
-      while (hue > 360)
-        hue -= 360;
-      while (hue < 0)
-        hue += 360;
-      
-      if (hue < 60)
-        g = m1 + (m2 - m1) * hue / 60;
-      else if (hue < 180)
-        g = m2;
-      else if (hue < 240)
-        g = m1 + (m2 - m1) * (240 - hue) / 60;
-      else
-        g = m1;
-      
-      hue = *h - 120;
-      while (hue > 360)
-        hue -= 360;
-      while (hue < 0)
-        hue += 360;
-      
-      if (hue < 60)
-        b = m1 + (m2 - m1) * hue / 60;
-      else if (hue < 180)
-        b = m2;
-      else if (hue < 240)
-        b = m1 + (m2 - m1) * (240 - hue) / 60;
-      else
-        b = m1;
-      
-      *h = r;
-      *l = g;
-      *s = b;
-    }
-}
-
 static void
 _shade_color (GdkRGBA *color,
               gdouble  factor)
 {
-  GdkRGBA temp;
+  GtkHSLA hsla;
 
-  temp = *color;
-  rgb_to_hls (&temp.red, &temp.green, &temp.blue);
+  _gtk_hsla_init_from_rgba (&hsla, color);
 
-  temp.green *= factor;
-  if (temp.green > 1.0)
-    temp.green = 1.0;
-  else if (temp.green < 0.0)
-    temp.green = 0.0;
+  hsla.lightness *= factor;
+  hsla.lightness = CLAMP (hsla.lightness, 0.0, 1.0);
 
-  temp.blue *= factor;
-  if (temp.blue > 1.0)
-    temp.blue = 1.0;
-  else if (temp.blue < 0.0)
-    temp.blue = 0.0;
+  hsla.hue *= factor;
+  hsla.hue = CLAMP (hsla.hue, 0.0, 1.0);
 
-  hls_to_rgb (&temp.red, &temp.green, &temp.blue);
-  *color = temp;
+  _gdk_rgba_init_from_hsla (color, &hsla);
 }
 
 /**